﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AstarTest
{
    class Square
    {
        public int X { get; set; }
        public int Y { get; set; }
        public bool IsStart { get; set; }
        public bool IsEnd { get; set; }

        private double localCost; // cost of getting from this square to goal
        private double parentCost; // cost of getting from parent square to this node
        private double passThroughCost;// cost of getting from the start to the goal
        // through this square

        private Maze maze;
        public HashSet<Square> Adjacencies { get; set; }

        public Square Parent { get; set; }
        private Random random;

        public Square(int x, int y, Maze maze)
        {

            this.X = x;
            this.Y = y;
            this.maze = maze;

            this.Adjacencies = new HashSet<Square>();
            random = new Random();
        }

        public void calculateAdjacencies()
        {

            int top = X - 1;
            int bottom = X + 1;
            int left = Y - 1;
            int right = Y + 1;

            if (bottom < maze.Rows)
            {
                if (isAdjacent())
                {
                    maze.getSquare(bottom, Y).addAdjacency(this);
                    this.addAdjacency(maze.getSquare(bottom, Y));
                }
            }

            if (right < maze.Columns)
            {
                if (isAdjacent())
                {
                    maze.getSquare(X, right).addAdjacency(this);
                    this.addAdjacency(maze.getSquare(X, right));
                }
            }
        }

        public void addAdjacency(Square square)
        {

            Adjacencies.Add(square);
        }

        public void removeAdjacency(Square square)
        {
            Adjacencies.Remove(square);
        }

        public double getPassThrough(Square goal)
        {

            if (this.IsStart)
            {
                return 0.0;
            }

            return getLocalCost(goal) + getParentCost();
        }

        public double getLocalCost(Square goal)
        {

            if (this.IsStart)
            {
                return 0.0;
            }

            localCost = 1.0 * (Math.Abs(X - goal.X) + Math.Abs(Y - goal.Y));
            return localCost;
        }

        public double getParentCost()
        {

            if (this.IsStart)
            {
                return 0.0;
            }

            if (parentCost == 0.0)
            {
                parentCost = 1.0 + .5 * (Parent.getParentCost() - 1.0);
            }

            return parentCost;
        }

        public bool isAdjacent()
        {
            double randomDouble = this.random.NextDouble(); // Random double between 0.0 and 1.0

            if (randomDouble > .5)
            {
                return true;
            }
            return true;
        }
    }
}
